<?php

/**
 * Name: 通知服务层
 * User: Silent
 * Date: 2025-11-07
 * Time: 16:00:00
 */

namespace App\Services\Checkin;

use App\Models\Checkin\NotificationLog;
use App\Repositories\Checkin\NotificationLogRepository;
use App\Repositories\Auth\WechatUserRepository;
use App\Services\BaseService;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\Log;
use Exception;

class NotificationService extends BaseService
{
    protected $notificationLogRepository;
    protected $wechatUserRepository;
    protected $wechatApp;

    public function __construct(
        NotificationLogRepository $notificationLogRepository,
        WechatUserRepository $wechatUserRepository
    ) {
        $this->notificationLogRepository = $notificationLogRepository;
        $this->wechatUserRepository = $wechatUserRepository;
        $this->initWechatApp();
    }

    /**
     * 初始化微信应用
     */
    private function initWechatApp()
    {
        try {
            $config = config('wechat.mini_program.default');
            $this->wechatApp = Factory::miniProgram($config);
        } catch (Exception $e) {
            Log::error('初始化微信应用失败', ['error' => $e->getMessage()]);
        }
    }

    /**
     * 根据员工ID获取openid
     */
    private function getOpenidByEmployeeId($employeeId)
    {
        try {
            // 通过employee表的wechat_user_id关联查询
            $employee = \App\Models\Config\Employee::with('wechatUser')->find($employeeId);

            if (!$employee || !$employee->wechatUser) {
                Log::warning('未找到员工的微信信息', ['employee_id' => $employeeId]);
                return null;
            }

            return $employee->wechatUser->openid ?? null;
        } catch (Exception $e) {
            Log::error('获取员工openid失败', [
                'employee_id' => $employeeId,
                'error' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * 发送签到通知给当班班长
     */
    public function sendSignInNotification($dutyLeader, $signRecord)
    {
        try {
            $message = $this->buildSignInMessage($signRecord);

            $notificationData = [
                'type' => NotificationLog::TYPE_SIGN_IN,
                'recipient_id' => $dutyLeader->id,
                'recipient_name' => $dutyLeader->name,
                'related_id' => $signRecord->id,
                'related_date' => $signRecord->sign_date,
                'message_content' => $message
            ];

            return $this->sendNotification($notificationData);

        } catch (Exception $e) {
            Log::error('发送签到通知失败', [
                'error' => $e->getMessage(),
                'duty_leader_id' => $dutyLeader->id ?? null,
                'sign_record_id' => $signRecord->id ?? null
            ]);

            return false;
        }
    }

    /**
     * 发送当班班长提醒
     */
    public function sendDutyLeaderNotification($dutyLeader)
    {
        try {
            // 构建订阅消息数据
            $subscribeData = $this->buildDutySubscribeData($dutyLeader, 'leader');
            $notificationData = [
                'type' => NotificationLog::TYPE_DUTY_LEADER,
                'recipient_id' => $dutyLeader->leader_id,
                'recipient_name' => $dutyLeader->leader_name,
                'related_id' => $dutyLeader->id,
                'related_date' => $dutyLeader->duty_date,
                'subscribe_data' => $subscribeData
            ];

            return $this->sendNotification($notificationData);

        } catch (Exception $e) {
            Log::error('发送当班班长提醒失败', [
                'error' => $e->getMessage(),
                'duty_leader_id' => $dutyLeader->id ?? null
            ]);

            return false;
        }
    }

    /**
     * 发送值班领导提醒
     */
    public function sendDutySupervisorNotification($dutySupervisor)
    {
        try {
            // 构建订阅消息数据
            $subscribeData = $this->buildDutySubscribeData($dutySupervisor, 'supervisor');

            $notificationData = [
                'type' => NotificationLog::TYPE_DUTY_SUPERVISOR,
                'recipient_id' => $dutySupervisor->supervisor_id,
                'recipient_name' => $dutySupervisor->supervisor_name,
                'related_id' => $dutySupervisor->id,
                'related_date' => $dutySupervisor->duty_date,
                'subscribe_data' => $subscribeData
            ];

            return $this->sendNotification($notificationData);

        } catch (Exception $e) {
            Log::error('发送值班领导提醒失败', [
                'error' => $e->getMessage(),
                'duty_supervisor_id' => $dutySupervisor->id ?? null
            ]);

            return false;
        }
    }

    /**
     * 发送异常审核通知
     */
    public function sendAbnormalReviewNotification($review)
    {
        try {
            // 这里可以根据需要发送给值班领导或其他相关人员
            $message = $this->buildAbnormalReviewMessage($review);

            $notificationData = [
                'type' => NotificationLog::TYPE_ABNORMAL_CHECKIN,
                'recipient_id' => 0, // 需要根据实际业务确定接收人
                'recipient_name' => '值班领导',
                'related_id' => $review->id,
                'related_date' => $review->review_date,
                'message_content' => $message
            ];

            // 暂时记录日志，实际发送需要确定接收人
            Log::info('异常审核通知', $notificationData);

            return true;

        } catch (Exception $e) {
            Log::error('发送异常审核通知失败', [
                'error' => $e->getMessage(),
                'review_id' => $review->id ?? null
            ]);

            return false;
        }
    }

    /**
     * 发送通知的核心方法
     */
    private function sendNotification($notificationData)
    {
        try {
            // 创建通知记录
            $notificationLog = $this->notificationLogRepository->createNotification($notificationData);

            // 如果微信应用未初始化，直接标记为失败
            if (!$this->wechatApp) {
                $this->notificationLogRepository->markAsFailed(
                    $notificationLog->id,
                    '微信应用未正确配置'
                );
                return false;
            }

            // 发送微信消息
            $result = $this->sendWechatMessage($notificationData);

            if ($result['success']) {
                $this->notificationLogRepository->markAsSent(
                    $notificationLog->id,
                    $result['message']
                );
                return true;
            } else {
                $this->notificationLogRepository->markAsFailed(
                    $notificationLog->id,
                    $result['message']
                );
                return false;
            }

        } catch (Exception $e) {
            Log::error('发送通知失败', [
                'error' => $e->getMessage(),
                'notification_data' => $notificationData
            ]);

            return false;
        }
    }

    /**
     * 发送微信消息
     */
    private function sendWechatMessage($notificationData)
    {
        try {
            // 获取用户的openid
            $openid = $this->getOpenidByEmployeeId($notificationData['recipient_id']);

            if (!$openid) {
                Log::warning('无法发送微信消息，未找到openid', [
                    'recipient_id' => $notificationData['recipient_id'],
                    'recipient_name' => $notificationData['recipient_name']
                ]);

                return [
                    'success' => false,
                    'message' => '未找到用户的微信信息'
                ];
            }

            // 如果有订阅消息数据，则发送订阅消息
            if (isset($notificationData['subscribe_data'])) {
                return $this->sendSubscribeMessage(
                    $openid,
                    $notificationData['subscribe_data']
                );
            }

            // 暂时模拟发送成功（如果不是订阅消息）
            Log::info('微信消息发送', [
                'recipient' => $notificationData['recipient_name'],
                'openid' => $openid,
                'message' => $notificationData['message_content']
            ]);

            return [
                'success' => true,
                'message' => '发送成功'
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '发送失败：' . $e->getMessage()
            ];
        }
    }

    /**
     * 发送订阅消息
     */
    private function sendSubscribeMessage($openid, $subscribeData)
    {
        try {
            $templateId = $subscribeData['template_id'];
            $data = $subscribeData['data'];
            $page = $subscribeData['page'] ?? 'pages/index/index';

            // 调用微信小程序订阅消息API
            $result = $this->wechatApp->subscribe_message->send([
                'touser' => $openid,
                'template_id' => $templateId,
                'page' => $page,
                'data' => $data,
            ]);

            Log::info('订阅消息发送结果', [
                'openid' => $openid,
                'template_id' => $templateId,
                'result' => $result
            ]);

            // EasyWeChat 返回的结果，errcode为0表示成功
            if (isset($result['errcode']) && $result['errcode'] === 0) {
                return [
                    'success' => true,
                    'message' => '订阅消息发送成功'
                ];
            } else {
                $errorMsg = $result['errmsg'] ?? '未知错误';
                return [
                    'success' => false,
                    'message' => '订阅消息发送失败：' . $errorMsg
                ];
            }

        } catch (Exception $e) {
            Log::error('发送订阅消息异常', [
                'openid' => $openid,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return [
                'success' => false,
                'message' => '发送订阅消息异常：' . $e->getMessage()
            ];
        }
    }



    /**
     * 构建值班安排提醒的订阅消息数据
     *
     * @param object $dutyData 值班数据（可以是当班班长或值班领导）
     * @param string $type 类型：leader 或 supervisor
     * @return array
     */
    private function buildDutySubscribeData($dutyData, $type = 'leader')
    {
        // 获取当前操作用户（发布人）
        $publisher = request()->input('current_user');
        $publisherName = $publisher ? $publisher->name : '系统';

        // 根据类型获取对应的数据
        if ($type === 'supervisor') {
            $dutyDate = $dutyData->duty_date;
            $name = $dutyData->supervisor_name;
            $remark = $dutyData->remark ?? '请保持通讯畅通，关注安全生产情况';
        } else {
            $dutyDate = $dutyData->duty_date;
            $name = $dutyData->leader_name;
            $teamName = $dutyData->team_name ?? '';
            // 如果有remark字段则使用，否则使用班组名称
            $remark = $dutyData->remark ?? "班组：{$teamName}";
        }

        // 获取模板ID
        $templateId = config('wechat.subscribe_message_templates.duty_reminder');

        // 格式化日期时间 - 确保符合微信订阅消息格式要求
        $formattedDutyDate = is_string($dutyDate) ? $dutyDate : $dutyDate->format('Y-m-d');
        $currentTime = date('Y-m-d H:i:s');

        // 构建订阅消息数据
        return [
            'template_id' => $templateId,
            'page' => 'pages/duty/index',
            'data' => [
                'time1' => [
                    'value' => $formattedDutyDate
                ],
                'thing4' => [
                    'value' => mb_substr($name, 0, 20) // 限制20个字符
                ],
                // 'thing11' => [
                //     'value' => mb_substr($publisherName, 0, 20) // 限制20个字符
                // ],
                'time10' => [
                    'value' => $currentTime
                ],
                'thing3' => [
                    'value' => mb_substr($remark, 0, 20) // 限制20个字符
                ]
            ]
        ];
    }

    /**
     * 处理待发送的通知队列
     */
    public function processPendingNotifications()
    {
        try {
            $pendingNotifications = $this->notificationLogRepository->getPendingNotifications();

            $successCount = 0;
            $failCount = 0;

            foreach ($pendingNotifications as $notification) {
                $result = $this->sendWechatMessage([
                    'recipient_id' => $notification->recipient_id,
                    'recipient_name' => $notification->recipient_name,
                    'message_content' => $notification->message_content
                ]);

                if ($result['success']) {
                    $this->notificationLogRepository->markAsSent(
                        $notification->id,
                        $result['message']
                    );
                    $successCount++;
                } else {
                    $this->notificationLogRepository->markAsFailed(
                        $notification->id,
                        $result['message']
                    );
                    $failCount++;
                }
            }

            Log::info('通知队列处理完成', [
                'total' => count($pendingNotifications),
                'success' => $successCount,
                'failed' => $failCount
            ]);

            return [
                'success' => true,
                'data' => [
                    'total' => count($pendingNotifications),
                    'success' => $successCount,
                    'failed' => $failCount
                ]
            ];

        } catch (Exception $e) {
            Log::error('处理通知队列失败', ['error' => $e->getMessage()]);

            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
}

